#ifndef _RESMAN_H_
#define _RESMAN_H_

#include <vector>
#include "resource_file.h"
#include "num/named_set.h"

namespace res
{
class ResMan
{
public:
	/// Constructor function
    typedef ResourceFile* (*CreateResFunc)();	
	struct	ResourceCreator
	{
		CreateResFunc				pFunc;
		std::vector<std::string>	AltPaths;
	};

	/// Singleton accessor
	static ResMan&	Instance();

	/// find the resource. load it if not found
	ResourceFile*		GetResource(const std::string& _Name);
	/// does the resource exist ?
	bool			ResourceExists(const std::string& _Name);
	/// flush the data-set.
	void			Flush();
    void			FlushData();
	void			FlushTextures();
	void			FlushTexturesExceptUI();

	/// release resource, but keep the data needed to re-validate it
	void			ReleaseResource(const std::string& Name);

	void			ReleaseAll();
	void			ReleaseExceptUI();
	void			ReinitAll();

	/// add new creator function to the set
	void			AddResourceConstructor(CreateResFunc _Func, const std::string& _Ext);
	void			AddAlternativePath(const std::string& Ext, const std::string& AltPath);

	// diagnistic functions
	void			GetTexMemory(unsigned int& TexC, unsigned int &TexMem, unsigned int &TexMemComp, unsigned int &TexMemFullC, unsigned int &TexMemPal, bool Output);

	/// Maps
	num::NamedSet<ResourceCreator*>		m_CreatorMap;
	num::NamedSet<ResourceFile*>			m_ResourceMap;
    
    void            SetForceSkipInit(bool b) { m_IsForceSkipInit = b; };
    bool            IsForceSkipInit() { return  m_IsForceSkipInit; };

	void			AddUIToMap(const std::string& Name);
    
private:

	num::NamedSet<ResourceFile*>		m_UIResourceMap;

	/// load it if it doesn't exist
	ResourceFile*			LoadResource(const std::string& _Name);
	/// find the creator to use for a specific file-type
	ResourceCreator*	GetCreatorFromName(const std::string& _Name);

	std::string		GetExtension(const std::string& _Name);

	/// Constructor
	ResMan();
	/// Destructor
	~ResMan();

	// prevent copying
    ResMan( const ResMan & );     
    ResMan & operator=( const ResMan & );

	/// ResourceFile callbacks
	static void			FlushResource(ResourceFile* pRes, void* pData);
	static void			ReleaseResource(ResourceFile* pRes, void* pData);
	static void			ReinitResource(ResourceFile* pRes, void* pData);

	/// ResourceFile tracking ?
	//	unsigned int	m_CurrentSize;
	//	unsigned int	m_MaxSize;
    
    bool                m_IsForceSkipInit;

};

} // namespace res

#endif // _RESMAN_H_